#include "SclXReader.h"
#include "Scene.h"
#include "Node.h"

SclXReader::SclXReader()
{}

Scene* SclXReader::readFile(QIODevice* device) {
	xml.setDevice(device);
	if (xml.readNextStartElement()) {
		Node* root = readNode();
		if (root == 0) return 0;
		return new Scene(root);
	}
	return 0;
}

Node* SclXReader::readNode() {
	Node* node = createNodeFromName(xml.name());
	if (node == 0) {
		xml.raiseError(QObject::tr("Can't recognize node type!"));
		return 0;
	}

	QXmlStreamAttributes& attrs = xml.attributes();
	node->name = attrs.value("name").toString();
	node->setX(attrs.value("x").toString().toFloat());
	node->setY(attrs.value("y").toString().toFloat());

	//read properties
	bool hasChildren = false;
	while(xml.readNextStartElement()) {
		if (xml.name() == "attribute") {
			node->attr[xml.attributes().value("key").toString()] = QVariant(xml.attributes().value("value").toString());
			xml.skipCurrentElement();
		} else {
			hasChildren = true;
			break;
		}
	}

	//read children
	if (hasChildren) {
		Node* ch;
		while (ch = readNode()) {
			node->addChild(ch);
			if (!xml.readNextStartElement())
				break;
		}
	}
	if (!xml.isEndElement())
		xml.skipCurrentElement();
	
	return node;
}

Node* SclXReader::createNodeFromName(const QStringRef& name) {
	if (name == "empty")
		return Scene::createEmpty();
	if (name == "sprite")
		return Scene::createSprite();
	if (name == "layer")
		return Scene::createLayer();
	return 0;
}

QString SclXReader::errorString() const {
	return QObject::tr("%1\nLine %2, column %3")
		.arg(xml.errorString())
		.arg(xml.lineNumber())
		.arg(xml.columnNumber());
}
